package com.commerce.constellation.view;

import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;

import java.util.concurrent.atomic.AtomicInteger;

public class PathAnimator extends AbstractPathAnimator {
    //线程安全的一个加减操作接口  (mCounter=0)
    private final AtomicInteger mCounter = new AtomicInteger(0);
    private Handler mHandler;

    public PathAnimator(Config config) {
        super(config);
        mHandler = new Handler(Looper.getMainLooper());
    }

    @Override
    public void start(final View child, final ViewGroup parent) {
        //使用指定的布局参数创建子视图
        parent.addView(child, new ViewGroup.LayoutParams(mConfig.heartWidth, mConfig.heartHeight));
        //初始化动画
        FloatAnimation anim = new FloatAnimation(createPath(parent, 2), randomRotation(), parent, child);
        //动画持续时间
        anim.setDuration(mConfig.animDuration);
        //设置此动画的加速度曲线   变化率恒定的插值器
        anim.setInterpolator(new LinearInterpolator());
        //将动画侦听器绑定到此动画。动画侦听器通知动画事件
        anim.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationEnd(Animation animation) {
                //动画结束
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        //移除
                        parent.removeView(child);
                    }
                });
                //当前值递减一（mCounter++）
                mCounter.decrementAndGet();
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
               //动画重复
            }

            @Override
            public void onAnimationStart(Animation animation) {
                //动画开始
                //当前值增加一
                mCounter.incrementAndGet();
            }
        });
         //现在开始指定的动画
        child.startAnimation(anim);
    }

    static class FloatAnimation extends Animation {
        private PathMeasure mPm;
        private View mView;
        private float mDistance;
        private float mRotation;

        /**
         * 构造方法
         * @param path  路径
         * @param rotation 偏移数
         * @param parent   视图
         * @param child    子视图
         */
        public FloatAnimation(Path path, float rotation, View parent, View child) {
            //计算初始化方式
            mPm = new PathMeasure(path, false);
            //获取到的是当前曲线的长度，而不是整个 Path 的长度
            mDistance = mPm.getLength();
            mView = child;
            mRotation = rotation;
            //指定图层类型        指示视图具有硬件层
            //不加这个节省15% gpu
//            parent.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        }
        //在绘制动画的过程中会反复的调用applyTransformation函数，
        // 每次调用参数factor值都会变化，该参数从0渐 变为1，当该参数为1时表明动画结束。
        // 通过参数transformation 来获取变换的矩阵（matrix），通过改变矩阵就可以实现各种复杂的效果
        @Override
        protected void applyTransformation(float factor, Transformation transformation) {
            Matrix matrix = transformation.getMatrix();

            mPm.getMatrix(mDistance * factor/*关联路径的距离*/, matrix, PathMeasure.POSITION_MATRIX_FLAG);
            //设置视图围绕轴点旋转的度数。
            // 增加值将导致顺时针旋转
            mView.setRotation(mRotation * factor);
            float scale = 1F;
            //缩放值，这缩放值网上看的
            if (3000.0F * factor < 200.0F) {
                scale = scale(factor, 0.0D, 0.06666667014360428D, 0.20000000298023224D, 1.100000023841858D);
            } else if (3000.0F * factor < 300.0F) {
                scale = scale(factor, 0.06666667014360428D, 0.10000000149011612D, 1.100000023841858D, 1.0D);
            }
            //设置视图围绕轴点在x和y轴上缩放的量
            mView.setScaleX(scale);
            mView.setScaleY(scale);
            //设置透明度
            transformation.setAlpha(1.0F - factor);
        }
    }

    private static float scale(double a, double b, double c, double d, double e) {
        return (float) ((a - b) / (c - b) * (e - d) + d);
    }
}


